﻿using System;
using System.Collections.Generic;
using System.Text;
using Rage.Base.Abilities;

namespace Rage.Juggernaut
{
    public class DefendModel
    {
        private CollectedCharacterJuggernaut CollChar;
        private float AttackSpeed;

        public readonly DefendTable DefendTable;

        public float AverageDamagePerAttack { get; set; }
        public float AverageDamagePerHit { get; set; }
        public float DamagePerHit { get; set; }
        public float DamagePerShield { get; set; }
        public float DamagePerCrit { get; set; }
        public float DamagePerSecond { get; set; }
        public float GuaranteedReduction { get; set; }
        public float Mitigation { get; set; }
        public float EffectiveHealth { get; set; }
        public float BurstTime { get; set; }

        public float AttackerSwingsPerSecond
        {
            get { return (1.0f / AttackSpeed); }
        }
        public float AttackerHitsPerSecond
        {
            get { return (AttackerSwingsPerSecond * DefendTable.AnyLand); }
        }

        public void Calculate()
        {
            float armorReduction        = 1f - StatConversion.GetArmorDamageReduction(CollChar.StatS.Armor, 0f, 0f);
            float guaranteedReduction   = CombatFactors.PlayersDamageReductionFromStance(CollChar, CollChar.CalcOpts.Stance) * armorReduction;
            float baseDamagePerSecond   = CollChar.BossOpts.DefaultMeleeAttack.DamagePerHit / AttackSpeed;
            float baseAttack            = CollChar.BossOpts.DefaultMeleeAttack.DamagePerHit * guaranteedReduction;

            DamagePerHit    = baseAttack   * (1.0f - CollChar.StatS.PhysicalDamageTakenReductionMultiplier) * (1.0f - CollChar.StatS.BossPhysicalDamageDealtReductionMultiplier);
            DamagePerCrit   = DamagePerHit * 1.50f;
            DamagePerShield = DamagePerHit * (1.0f - CollChar.StatS.Absorb);

            AverageDamagePerHit =
                DamagePerHit * (DefendTable.Hit / DefendTable.AnyLand) +
                DamagePerCrit * (DefendTable.Crit / DefendTable.AnyLand) +
                DamagePerShield * (DefendTable.Shield / DefendTable.AnyLand);
            AverageDamagePerAttack =
                DamagePerHit * DefendTable.Hit +
                DamagePerCrit * DefendTable.Crit +
                DamagePerShield * DefendTable.Shield;

            DamagePerSecond = AverageDamagePerAttack / AttackSpeed;
            Mitigation              = (1.0f - (DamagePerSecond / baseDamagePerSecond));
            EffectiveHealth         = (CollChar.StatS.Health / guaranteedReduction);
            GuaranteedReduction     = (1.0f - guaranteedReduction);

            double a = Convert.ToDouble(DefendTable.AnyMiss);
            double h = Convert.ToDouble(CollChar.StatS.Health);
            double H = Convert.ToDouble(AverageDamagePerHit);
            double s = Convert.ToDouble(AttackSpeed);
            BurstTime = Convert.ToSingle((1.0d / a) * ((1.0d / Math.Pow(1.0d - a, h / H)) - 1.0d) * s);
        }

        public DefendModel(CollectedCharacterJuggernaut collChar)
        {
            CollChar      = collChar;
            AttackSpeed = CollChar.BossOpts.DefaultMeleeAttack.AttackSpeed;
            DefendTable = new DefendTable(CollChar.Char, CollChar.StatS,
                CollChar.CombatFactors, CollChar.BossOpts, null, true, false);
            Calculate();
        }
    }
}
